package com.zongtui.fourinone.base.config;

import com.zongtui.fourinone.base.BeanContext;
import com.zongtui.fourinone.base.config.xml.XmlUtil;
import com.zongtui.fourinone.file.FileAdapter;
import com.zongtui.fourinone.obj.ObjValue;
import com.zongtui.fourinone.utils.log.LogUtil;

import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;

/**
 * 系统配置类.目前是从两个地方获取配置信息。一个是config.properties.一个是config.xml
 */
public class ConfigContext {
    private static MulBean mb = null;
    /**
     * 传输协议时间接口 默认值是:sun.rmi.transport.tcp.responseTimeout
     */
    private static String TransportTimeout = null;
    /**
     * 默认值是:java.rmi.server.hostname
     */
    private static String RemoteHostName = null;
    /**
     * 日志调用实现。默认值是：java.rmi.server.logCalls
     */
    private static String LogCalls = null;

    /**
     * 远程调用协议，默认值是：rmi://
     */
    private static String RemoteCallProtocol = null;
    /**
     * 默认值是：java.rmi.server.codebase
     */
    private static String RemoteCodebase = null;
    /**
     * 安全策略，默认值是：java.security.policy
     */
    private static String SecurityPolicy = null;
    /**
     * 安全协议：默认值是：grant{permission java.security.AllPermission;};
     */
    private static String Policy = null;
    /**
     * 临时目录 ，默认值是：java.io.tmpdir
     */
    private static String TmpDir = null;

    private static String serviceOnWorker = null;

    private static long workerTimeout = -1;

    /**
     * 默认的config路径指向项目根目录下.
     */
    public static String configFile = new File("").getAbsolutePath() + File.separator + "config.xml";

    private static ObjValue users = null;

    //coolhash里面取出来的对象.

    /**
     * key长度设置.
     */
    private static long keyLength = -1;
    /**
     * 值长度设置.
     */
    private static long valueLength = -1;
    /**
     * 默认区长度.
     */
    private static long regionLength = -1;
    /**
     * 默认负载长度.
     */
    private static long loadLength = -1;
    /**
     * 默认哈希容量.
     */
    private static int hashCapacity = -1;
    /**
     * 设置数据根.
     */
    private static String dataRoot;

    /**
     * 获取默认key长度.[default 256]
     *
     * @return 获取默认key长度.[default 256]
     */
    public static long getKeyLength() {
        if (keyLength == -1) {
            keyLength = new Long(getConfig("coolHash", "keyLength", "B", "256"));
        }
        return keyLength;
    }


    /**
     * 获取默认值长度：【2】
     *
     * @return 获取默认值长度：【2】
     */
    public static long getValueLength() {
        if (valueLength == -1) {
            valueLength = new Long(getConfig("coolHash", "valueLength", "M", "2"));
        }
        return valueLength;
    }

    /**
     * 获取默认区长度：【2】
     *
     * @return 获取默认区长度：【2】
     */
    public static long getRegionLength() {
        if (regionLength == -1)
            regionLength = new Long(getConfig("coolHash", "regionLength", "M",
                    "2"));
        return regionLength;
    }

    /**
     * 获取 默认负载长度：【64】
     *
     * @return 获取 默认负载长度：【64】
     */
    public static long getLoadLength() {
        if (loadLength == -1)
            loadLength = new Long(
                    getConfig("coolHash", "loadLength", "M", "64"));
        return loadLength;
    }

    /**
     * 获取默认哈希容量：【1000000】
     *
     * @return 获取默认哈希容量：【1000000】
     */
    public static int getHashCapacity() {
        if (hashCapacity == -1)
            hashCapacity = new Integer(getConfig("coolHash", "hashCapacity",
                    null, "1000000"));
        return hashCapacity;
    }

    /**
     * 获取根节点：【data】
     *
     * @return 获取根节点：【data】
     */
    public static String getDataRoot() {
        if (dataRoot == null)
            dataRoot = getConfig("coolHash", "dataRoot", null, "data");
        return dataRoot;
    }

    /**
     * 获得初始化的资源bean.
     *
     * @return 获得初始化的资源bean.
     */
    static MulBean getMulBean() {
        return mb != null ? mb : new MulBean("ISO-8859-1");
    }

    /**
     * 获取传输超时时间接口
     *
     * @return 获取传输超时时间接口
     */
    public static String getTransportTimeout() {
        if (TransportTimeout == null)
            TransportTimeout = getMulBean().getString("TransportTimeout");
        return TransportTimeout;
    }

    public static String getRemoteHostName() {
        if (RemoteHostName == null)
            RemoteHostName = getMulBean().getString("RemoteHostName");
        return RemoteHostName;
    }

    public static String getLogCalls() {
        if (LogCalls == null)
            LogCalls = getMulBean().getString("LogCalls");
        return LogCalls;
    }

    static String getRemoteCallProtocol() {
        if (RemoteCallProtocol == null)
            RemoteCallProtocol = getMulBean().getString("RemoteCallProtocol");
        return RemoteCallProtocol;
    }

    public static String getRemoteCodebase() {
        if (RemoteCodebase == null)
            RemoteCodebase = getMulBean().getString("RemoteCodebase");
        return RemoteCodebase;
    }

    public static String getSecurityPolicy() {
        if (SecurityPolicy == null)
            SecurityPolicy = getMulBean().getString("SecurityPolicy");
        return SecurityPolicy;
    }

    static String getPolicy() {
        if (Policy == null)
            Policy = getMulBean().getString("Policy");
        return Policy;
    }

    static String getTmpDir() {
        if (TmpDir == null)
            TmpDir = getMulBean().getString("TmpDir");
        return TmpDir;
    }

    public static String getProp(String propstr) {
        return getMulBean().getString(propstr);
    }

    /**
     * 获取协议信息。规则：域名:端口/名称 eg:rmi://10.5.12.12:8080/demo
     *
     * @param host 域名
     * @param port 端口
     * @param name 名称
     * @return 完成的url信息
     */
    public static String getProtocolInfo(String host, int port, String name) {
        //默认远程调用协议是rmi.
        return getRemoteCallProtocol() + host + ":" + port + "/" + name;
    }

    public static long getWorkerTimeout() {
        if (workerTimeout == -1)
            workerTimeout = getSecTime(new Double(getConfig("worker", "timeout", "true", "0")));
        return workerTimeout;
    }

    public static boolean getServiceFlag() {
        if (serviceOnWorker == null)
            serviceOnWorker = getConfig("worker", "service", null, "false");
        return Boolean.parseBoolean(serviceOnWorker);
    }

    public static long getSecTime(Double hours) {
        Double t = hours * 3600 * 1000;
        return t.longValue();
    }

    public static String[][] getParkConfig() {
        String servers = getConfig("park", "servers", null);
        return getServerFromStr(servers);
    }

    public static String getParkService() {
        return getConfig("park", "service", null);
    }

    static String[] getCtorService() {
        return getConfig("ctor", "ctorServers", null).split(":");
    }

    public static String[] getFttpConfig() {
        return getConfig("fttp", "servers", null).split(":");
    }

    public static String[] getInetConfig() {
        return getConfig("webApp", "servers", null).split(":");
    }

    public static ObjValue getUsersConfig() {
        if (users == null) {
            String userstr = getConfig("webApp", "users", null);
            users = getObjFromStr(userstr);
        }
        return users;
    }

    public static String getInternetStrConfig(String dir) {
        String internetStr = "http://" + getConfig("webApp", "servers", null)
                + "/res/";
        return dir != null ? internetStr + dir : internetStr;
    }

    public static String getPolicyConfig() {
        String tdir = System.getProperty(getTmpDir());
        File fl = new File(tdir, "a.pl");
        if (!fl.exists()) {
            FileAdapter fa = new FileAdapter(fl.getPath());
            fa.getWriter().write(getPolicy().getBytes());
            fa.close();
        }
        return fl.getPath();
    }

    public static String[] getWorkerConfig() {
        return getConfig("worker", "servers", null).split(":");
    }

    public static String[][] getCacheConfig() {
        String servers = getConfig("cache", "servers", null);
        return getServerFromStr(servers);
    }

    public static String getCacheService() {
        return getConfig("cache", "service", null);
    }

    public static String[] getCacheFacadeConfig() {
        return getConfig("cacheFacade", "servers", null).split(":");
    }

    public static String getCacheFacadeService() {
        return getConfig("cacheFacade", "service", null);
    }

    public static int getInitServices() {
        int initnum = 10;
        try {
            initnum = Integer.parseInt(getConfig("ctor", "initServices", null, "10"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return initnum;
    }

    public static int getMaxServices() {
        int maxnum = 100;
        try {
            maxnum = Integer.parseInt(getConfig("ctor", "maxServices", null,
                    "100"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return maxnum;
    }

    public static int getParallelPattern() {
        return Integer.parseInt(getConfig("computeMode", "mode", "default"));
    }

    static String getConfig(String cfgname, String cfgprop, String cfgdesc) {
        return getConfig(cfgname, cfgprop, cfgdesc, null);
    }

    /**
     * 获得属性的值
     *
     * @param configName   属性节点名称
     * @param configProps  属性prop名称
     * @param configDesc   配置描述
     * @param defaultValue 缺省默认值
     * @return 属性的值
     */
    public static String getConfig(String configName, String configProps, String configDesc,
                                   String defaultValue) {
        XmlUtil xu = new XmlUtil();
        ArrayList al = xu.getXmlObjectByFile(configFile, configName, configDesc);
        String v = null;
        if (al != null && al.size() > 0) {
            ObjValue cfgProps = (ObjValue) al.get(0);
            v = cfgProps.getString(configProps);
        }
        if (v == null) {
            v = defaultValue;
        }
        return v;
    }

    public static String getLogLevel(String deflevel) {
        XmlUtil xu = new XmlUtil();
        ArrayList al = xu.getXmlPropsByFile(configFile, "log", "loglevel");
        Properties dbProps = (Properties) al.get(0);
        String levelName = dbProps.getProperty("levelName");

        return levelName != null ? levelName : deflevel;
    }

    public static ObjValue getCacheGroupConfig() {
        XmlUtil xu = new XmlUtil();
        ArrayList al = xu.getXmlObjectByFile(configFile, "cacheGroup");
        ObjValue groups = new ObjValue();

        for (Object anAl : al) {
            ObjValue cacheProps = (ObjValue) anAl;
            ObjValue gp = new ObjValue();
            String gpcfgstr = cacheProps.getString("group");
            for (String perstr : gpcfgstr.split(";")) {
                String[] perstrarr = perstr.split("@");
                gp.setObj(perstrarr[0], new Long(getDateLong(perstrarr[1])));
            }
            groups.put(gp, new Long(getDateLong(cacheProps.getString("startTime"))));
        }

        LogUtil.fine("[ConfigContext]", "[getCacheConfig]", groups);
        return groups;
    }

    public static String getDateLong(String dateStr) {
        if (dateStr != null && !dateStr.equals("")) {
            try {
                DateFormat dateFormat = DateFormat.getDateInstance();
                Date d = dateFormat.parse(dateStr);
                dateStr = d.getTime() + "";
                if (dateStr.length() == 12)
                    dateStr = "0" + dateStr;
            } catch (Exception e) {
                //noinspection ThrowablePrintedToSystemOut
                System.err.println(e);
            }
        }
        return dateStr;
    }

    public static String[][] getServerFromStr(String servers) {
        String[] serverArray = servers.split(",");
        String[][] sarr = new String[serverArray.length][];
        for (int n = 0; n < serverArray.length; n++) {
            String[] hostport = serverArray[n].split(":");
            sarr[n] = hostport;
        }

        return sarr;
    }

    private static ObjValue getObjFromStr(String strs) {
        String[] strarr = strs.split(",");
        ObjValue ov = new ObjValue();
        for (String thestr : strarr) {
            String[] str = thestr.split(":");
            ov.setString(str[0], str[1]);
        }

        return ov;
    }

    public static String getRequest(String requestUrl) {
        return getMulBean().getFileString(getMulBean().getString(requestUrl));
    }

    public static void main(String args[]) {
        BeanContext.setConfigFile("D://file");
        System.out.println(getParkConfig()[0][0]);
        LogUtil.fine(getCacheConfig());
        LogUtil.fine("getParallelPattern:" + getParallelPattern());
        System.out.println(getConfig("cacheFacade", "tryKeysNum", null, "500"));
    }
}